cmake_minimum_required(VERSION 3.22)

# ------ BSP -------

# ---- 默认Debug
if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Debug")
endif ()

# ---- 为 clangd 提供
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)

# ---- 启用 C 和 ASM
enable_language(C ASM)

# ---- 项目配置
project(bsp)

# ---- 接口库
add_library(${PROJECT_NAME} INTERFACE)


# ---- 添加源文件
if(USE_ARMCLANG)
    set(tool_chain_folder "armclang")
else ()
    set(tool_chain_folder "armgnu")
endif ()
file(GLOB_RECURSE source_files CONFIGURE_DEPENDS
        BSP/*.c BSP/*.cpp BSP/*.h ${tool_chain_folder}/startup_stm32g474xx.s
)

target_sources(${PROJECT_NAME} INTERFACE ${source_files})


# ---- 头文件目录
target_include_directories(${PROJECT_NAME} INTERFACE BSP/include)

# ------ 接管 stm32cubemx ------
# ---- 设置原始文件和目标文件的路径
set(CUBE_SOURCE_FILE "${CMAKE_CURRENT_LIST_DIR}/cmake/stm32cubemx/CMakeLists.txt")
set(CUBE_DESTINATION_FILE "${CMAKE_CURRENT_LIST_DIR}/BSP/stm32cubemx/CMakeLists.txt")


# ---- 字符串匹配删除
function(remove_string CONTENTS_VAR SUBSTRING)
    set(CONTENTS "${${CONTENTS_VAR}}")

    string(REPLACE "\r\n" "\n" CONTENTS "${CONTENTS}")
    string(REPLACE "\r" "\n" CONTENTS "${CONTENTS}")
    string(APPEND CONTENTS "\n")

    # 拆成行
    string(REPLACE "\n" ";" LINES "${CONTENTS}")

    set(NEW_LINES "")
    foreach(LINE IN LISTS LINES)
        if(NOT "${LINE}" MATCHES "${SUBSTRING}")
            list(APPEND NEW_LINES "${LINE}")
        endif()
    endforeach()

    string(REPLACE ";" "\n" RESULT "${NEW_LINES}")
    set(${CONTENTS_VAR} "${RESULT}" PARENT_SCOPE)
endfunction()


# ---- 读取原始文件内容
file(READ ${CUBE_SOURCE_FILE} CUBE_CONTENTS)

# ---- 删除 main.c
remove_string(CUBE_CONTENTS "main\.c")
# ---- 删除 startup_stm32g473xx.s
remove_string(CUBE_CONTENTS "startup_stm32g474xx\.s")
# ---- 删除 cube 配置的 usb 接口
remove_string(CUBE_CONTENTS "usbd_cdc_if\.c")
# ---- 支持cube6.15修改库连接写法
string(REPLACE "(\${CMAKE_PROJECT_NAME} \${MX_LINK_LIBS})" "(\${CMAKE_PROJECT_NAME} PRIVATE \${MX_LINK_LIBS})" CUBE_CONTENTS "${CUBE_CONTENTS}")

if(USE_ARMCLANG)
    # ---- 删除 sysmem.c和syscalls.c
    remove_string(CUBE_CONTENTS "sysmem\.c")
    remove_string(CUBE_CONTENTS "syscalls\.c")
    # ---- 修改链接库写法
    string(REPLACE ":libarm_cortexM4lf_math.a" "${CMAKE_SOURCE_DIR}/BSP/Middlewares/ST/ARM/DSP/Lib/libarm_cortexM4lf_math.a" CUBE_CONTENTS "${CUBE_CONTENTS}")
endif ()

# ---- 写入到目标文件
file(WRITE ${CUBE_DESTINATION_FILE} ${CUBE_CONTENTS})

# ------ 接管 main.c ==> bsp.cpp ------
# ---- 设置原始文件和目标文件的路径
set(BSP_SOURCE_FILE "${CMAKE_CURRENT_LIST_DIR}/Core/src/main.c")
set(BSP_DESTINATION_FILE "${CMAKE_CURRENT_LIST_DIR}/BSP/src/bsp.cpp")

# ---- 读取原始文件内容
file(READ ${BSP_SOURCE_FILE} BSP_CONTENTS)

# ---- main.h ==> bsp.h
string(REPLACE "#include \"main.h\"" "#include <bsp.h>" BSP_CONTENTS "${BSP_CONTENTS}")
string(REPLACE "int main(void)" "void bsp::Init()" BSP_CONTENTS "${BSP_CONTENTS}")
string(REPLACE "  /* USER CODE BEGIN WHILE */\n  while (1)" "" BSP_CONTENTS "${BSP_CONTENTS}")
string(REPLACE "SystemClock_Config();" "" BSP_CONTENTS "${BSP_CONTENTS}")
string(REPLACE "HAL_Init();" "" BSP_CONTENTS "${BSP_CONTENTS}")
string(REPLACE "void SystemClock_Config(void)" "void bsp::SystemClockConfig()" BSP_CONTENTS "${BSP_CONTENTS}")
string(REPLACE "osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);\n" "" BSP_CONTENTS "${BSP_CONTENTS}")
string(REPLACE "defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);\n" "" BSP_CONTENTS "${BSP_CONTENTS}")
string(REPLACE "osKernelStart();\n" "" BSP_CONTENTS "${BSP_CONTENTS}")


# ---- 写入到目标文件
file(WRITE ${BSP_DESTINATION_FILE} "${BSP_CONTENTS}")


# ------ 静态库 ------
# ---- 添加 stm32cubemx 库
add_subdirectory(BSP/stm32cubemx)
target_link_libraries(${PROJECT_NAME} INTERFACE stm32cubemx)
# ---- dsp
#target_link_directories(${PROJECT_NAME} INTERFACE dsp)
#target_link_libraries(${PROJECT_NAME} INTERFACE
#        "${CMAKE_CURRENT_LIST_DIR}/DSP/libarm_cortexM4l_math.a"
#        "${CMAKE_CURRENT_LIST_DIR}/DSP/libarm_cortexM4lf_math.a"
#)
#target_include_directories(${PROJECT_NAME} INTERFACE dsp)


